package cm.tl.pms.common.exception;

import cm.tl.pms.common.entity.ErrorEnum;
import cm.tl.pms.common.entity.ResultMsg;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotPermissionException;
import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import java.util.List;

@ControllerAdvice
public class GlobalExceptionHandler {

    public static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class.getName());

    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public ResultMsg<Object> handleValidationException(MethodArgumentNotValidException e) {
        BindingResult bindingResult = e.getBindingResult();
        List<FieldError> fieldErrors = bindingResult.getFieldErrors();
        StringBuilder errorMessageBuilder = new StringBuilder();
        for (FieldError fieldError : fieldErrors) {
            String errorMessage = fieldError.getDefaultMessage();
            errorMessageBuilder.append(errorMessage).append("; ");
        }

//        // 获取抛出异常的方法信息
//        Object target = bindingResult.getTarget();
//        if (target != null) {
//            String methodName = target.getClass().getSimpleName() + "." + bindingResult.getNestedPath();
//            log.warn("验证异常方法: " + methodName);
//        } else {
//            log.warn("Validation error occurred, unable to determine method information");
//        }
        ResultMsg<Object> resultRsp = new ResultMsg<>();
        resultRsp.setResultCode(ErrorEnum.PARAM_ERROR.getCode());
        resultRsp.setResultMsg(String.format("%s：%s", ErrorEnum.PARAM_ERROR.getMsg(), errorMessageBuilder.toString()));
        resultRsp.setData("");
        logger.warn(" resultRsp :" + JSON.toJSONString(resultRsp) + " 报错信息： " + e);
        return resultRsp;
    }

    //拦截那些传入空字符串的 字段绑定异常
    @ExceptionHandler(BindException.class)
    @ResponseBody
    public ResultMsg<Object> handleBindException(BindException e) {
        BindingResult bindingResult = e.getBindingResult();
        List<FieldError> fieldErrors = bindingResult.getFieldErrors();
        StringBuilder errorMessageBuilder = new StringBuilder();
        for (FieldError fieldError : fieldErrors) {
            String errorMessage = fieldError.getDefaultMessage();
            errorMessageBuilder.append(errorMessage).append("; ");
        }
        ResultMsg<Object> resultRsp = new ResultMsg<>();
        resultRsp.setResultCode(ErrorEnum.PARAM_ERROR.getCode());
        resultRsp.setResultMsg(String.format("%s：%s", ErrorEnum.PARAM_ERROR.getMsg(), errorMessageBuilder.toString()));
        resultRsp.setData("");
        logger.warn(" resultRsp :" + JSON.toJSONString(resultRsp) + " 报错信息： " + e);
        return resultRsp;
    }


    // @ExceptionHandler(IllegalArgumentException.class)
    // @ResponseBody
    // public ResultMsg<Object> handleIllegalArgumentException(IllegalArgumentException e) {
    //     // 解析异常逻辑
    //     String errorMessage = e.getMessage();
    //
    //     ResultMsg<Object> resultRsp = new ResultMsg<>();
    //     resultRsp.setResultCode(ErrorEnum.PARSING_FAILED_ERROR.getCode());
    //     resultRsp.setResultMsg(String.format("%s：%s", ErrorEnum.PARSING_FAILED_ERROR.getMsg(), errorMessage));
    //     resultRsp.setData("");
    //     logger.warn( " resultRsp :" + JSON.toJSONString(resultRsp) + " 报错信息： " + e);
    //     return resultRsp;
    // }


    @ExceptionHandler(EnumValuesException.class)
    @ResponseBody
    public ResultMsg<Object> handleEnumValusException(EnumValuesException e) {
        // 解析异常逻辑
        String errorMessage = e.getMessage();

        ResultMsg<Object> resultRsp = new ResultMsg<>();
        resultRsp.setResultCode(ErrorEnum.ERROR_ENUM10015.getCode());
        resultRsp.setResultMsg(String.format("%s：%s", ErrorEnum.ERROR_ENUM10015.getMsg(), errorMessage));
        resultRsp.setData("");
        logger.warn(" resultRsp :" + JSON.toJSONString(resultRsp) + " 报错信息： " + e);
        return resultRsp;
    }


    @ExceptionHandler(CustomErrorException.class)
    @ResponseBody
    public ResultMsg<Object> handleCustomBatchUpdateException(CustomErrorException e) {
        // 解析异常逻辑
        String errorMessage = e.getMessage();

        ResultMsg<Object> resultRsp = new ResultMsg<>();
        resultRsp.setResultCode(ErrorEnum.FALSE.getCode());
        resultRsp.setResultMsg(String.format("%s %s", ErrorEnum.FALSE.getMsg(), errorMessage));
        resultRsp.setData("");
        logger.error("resultRsp :" + JSON.toJSONString(resultRsp) + " 报错信息： " + e);
        return resultRsp;
    }

    @ExceptionHandler(CustomException.class)
    @ResponseBody
    public ResultMsg<Object> handleCustomBatchUpdateException(CustomException e) {
        // 解析异常逻辑
        String errorMessage = e.getMessage();

        ResultMsg<Object> resultRsp = new ResultMsg<>();
        resultRsp.setResultCode(ErrorEnum.FALSE.getCode());
        resultRsp.setResultMsg(String.format("%s %s", ErrorEnum.FALSE.getMsg(), errorMessage));
        resultRsp.setData("");
        logger.warn("resultRsp :" + JSON.toJSONString(resultRsp) + " 报错信息： " + e);
        return resultRsp;
    }


    @ExceptionHandler(DuplicateKeyException.class)
    @ResponseBody
    public ResultMsg<Object> handleDuplicateKeyException(DuplicateKeyException e) {
        // 解析异常逻辑
        String errorMessage = e.getMessage();

        ResultMsg<Object> resultRsp = new ResultMsg<>();
        resultRsp.setResultCode(ErrorEnum.FALSE.getCode());
        resultRsp.setResultMsg(String.format("%s %s", "唯一键重复", errorMessage));
        resultRsp.setData("");
        logger.warn("resultRsp :" + JSON.toJSONString(resultRsp) + " 报错信息： " + e);
        return resultRsp;
    }

    @ExceptionHandler(NotLoginException.class)
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    @ResponseBody
    public ResultMsg<Object> handlesNotLoginException(NotLoginException e) {
        // 解析异常逻辑
        String errorMessage = e.getMessage();

        ResultMsg<Object> resultRsp = new ResultMsg<>();
        resultRsp.setResultCode(ErrorEnum.FALSE.getCode());
        resultRsp.setResultMsg(String.format("%s %s", ErrorEnum.FALSE.getMsg(), errorMessage));
        resultRsp.setData("");
        logger.warn("resultRsp :" + JSON.toJSONString(resultRsp) + " 报错信息： " + e);
        return resultRsp;
    }


    @ExceptionHandler(NotPermissionException.class)
    @ResponseStatus(HttpStatus.FORBIDDEN)
    @ResponseBody
    public ResultMsg<Object> handlesNotPermissionException(NotPermissionException e) {
        // 解析异常逻辑
        String errorMessage = e.getMessage();

        ResultMsg<Object> resultRsp = new ResultMsg<>();
        resultRsp.setResultCode(ErrorEnum.FALSE.getCode());
        resultRsp.setResultMsg(String.format("%s %s", ErrorEnum.FALSE.getMsg(), errorMessage));
        resultRsp.setData("");
        logger.warn("resultRsp :" + JSON.toJSONString(resultRsp) + " 报错信息： " + e);
        return resultRsp;
    }
}
